/**
********************************************************************************
* @file     lv_port_indev_encoder.c
* @brief    对文件的简要说明
* @details  对文件的详细说明
* @author   jcai
* @date     2024-07-11 20:46:50
* @copyright Copyright &copy; 2024 wy1107412334@163.com All rights reserved
* @version  v0.0.1
*
* \n Email:  wy1107412334@163.com
* \n Blog:   None
* \n Github: https://github.com/wy1107412334
* \n Gitee:  https://gitee.com/git.git1107412334.com
*
********************************************************************************
* @note
* None.
********************************************************************************
* @attention
* None.
********************************************************************************
@verbatim
@endverbatim
********************************************************************************
* @par 历史记录
* jcai, 2024-07-11 20:46:50
* - 首次编写
*
*<center>Copyright &copy; 2024 wy1107412334@163.com All rights reserved</center>
********************************************************************************
*/

/* 头文件导入区 ------------------------------------------------------------- */

#include <stdio.h>
#include <stdlib.h>
#include <strings.h>

#if defined(LV_LVGL_H_INCLUDE_SIMPLE)
#include "lvgl.h"
#else
#include "lvgl/lvgl.h"
#endif
#include "lv_port_indev_encoder.h"
#include "sdl_render.h"


/** @defgroup LV_PORT_INDEV_ENCODER LV_PORT_INDEV_ENCODER
* @brief lv_port_indev_encoder modules
* @{
*/



/* 私有宏定义区 ------------------------------------------------------------- */






/* 私有数据类型声明区 ------------------------------------------------------- */

struct encoder_data
{
    sdl_event_handle_arr_t  eventsInfo;
    SDL_Event               cur;
    int16_t                 enc_diff;
};


static void encoder_event(const SDL_Event *, void *, void *);




/* 私有变量定义区 ----------------------------------------------------------- */

static sdl_event_handle_t events[] = {
    { .type = SDL_MOUSEBUTTONDOWN, .fn = encoder_event, .arg = NULL },
    { .type = SDL_MOUSEBUTTONUP, .fn = encoder_event, .arg = NULL },
    { .type = SDL_MOUSEWHEEL, .fn = encoder_event, .arg = NULL },
};




/** @defgroup LV_PORT_INDEV_ENCODER_Exported_Variables lv_port_indev_encoder exported variables
* @brief 全局变量定义
* @{
*/



/** defgroup LV_PORT_INDEV_ENCODER_Exported_Variables
* @}
*/





/* 私有函数定义区 ----------------------------------------------------------- */


/*Will be called by the library to read the encoder*/
static void encoder_read(lv_indev_t * indev_drv, lv_indev_data_t * data)
{
    struct encoder_data * p = lv_indev_get_driver_data(indev_drv);

    // 编码器的按键按下了
    if ((p->cur.type == SDL_MOUSEBUTTONDOWN) && (p->cur.button.state == SDL_PRESSED))
    {
        data->state = LV_INDEV_STATE_PRESSED;
        data->key = LV_KEY_ENTER;
    }
    // 编码器在旋转
    else if (p->cur.type == SDL_MOUSEWHEEL)
    {
        data->enc_diff = - p->enc_diff;

//        p->cur.type = SDL_FIRSTEVENT;
        p->enc_diff = 0;

        data->state = LV_INDEV_STATE_RELEASED;
    }
    else
    {
        data->state = LV_INDEV_STATE_RELEASED;
    }
}


static void encoder_event(const SDL_Event * e, void * lvglDrv, void * arg)
{
    (void) arg;

    struct encoder_data * p = lv_indev_get_driver_data(lvglDrv);
    int saveDataFlg = 0;

    // 鼠标按键事件
    if ((e->type == SDL_MOUSEBUTTONUP) || (e->type == SDL_MOUSEBUTTONDOWN))
    {
        // 鼠标滚轮键按下/抬起
        if (e->button.button == 2)
        {
            saveDataFlg = 1;
        }
    }
    // 鼠标滚轮事件
    else if (e->type == SDL_MOUSEWHEEL)
    {
        saveDataFlg = 1;
        p->enc_diff = e->wheel.y;
    }

    if (saveDataFlg)
    {
        p->cur = *e;
    }
}




/** @defgroup LV_PORT_INDEV_ENCODER_Exported_Functions lv_port_indev_encoder exported functions
* @brief 全局函数定义
* @{
*/



/**
********************************************************************************
* @brief    简要说明
* @details  详细说明
* @param    none
* @param[in]     a: 该参数用于输入
* @param[in,out] b: 该参数用于输入和输出
* @param[out]    c: 该参数用于输出
* @retval  none
* @retval  0 函数成功
* @retval  1 函数失败
* @return  返回0成功；否则失败
* @note    none
*/
void lv_port_indev_encoder_init(void)
{
    struct encoder_data * p = malloc(sizeof(*p));
    if (p == NULL)  return;
    bzero(p, sizeof(*p));

    lv_indev_t * indev_encoder = lv_indev_create();
    lv_indev_set_type(indev_encoder, LV_INDEV_TYPE_ENCODER);
    lv_indev_set_read_cb(indev_encoder, encoder_read);
    lv_indev_set_driver_data(indev_encoder, p);
    lv_indev_set_group(indev_encoder, lv_group_get_default()); /* 关联默认组 */

    p->eventsInfo.arr = events;
    p->eventsInfo.arrlen = sizeof(events) / sizeof(events[0]);
    p->eventsInfo.lvglDrv = indev_encoder;

    void * handle = lv_display_get_driver_data(lv_indev_get_display(indev_encoder));
    sdl_event_listen(handle, &p->eventsInfo);
}


/** defgroup LV_PORT_INDEV_ENCODER_Exported_Functions
* @}
*/

/** defgroup LV_PORT_INDEV_ENCODER
* @}
*/


/*********************************** END OF FILE ******************************/
